import { Types } from 'mongoose';
import NodeCache from 'node-cache';
import crypto from 'crypto';
import { logger } from '@utils/logger';
import { ApiError } from '@middleware/error';

interface ScoreData {
  userId: Types.ObjectId;
  subjectId: Types.ObjectId;
  answers: Array<{
    questionId: string;
    answer: string;
    weight?: number; // 题目权重
  }>;
}

interface ScoreResult {
  totalScore: number;
  details: Array<{
    questionId: string;
    score: number;
    feedback: string;
    weakPoints: string[];
    suggestions: string[];
  }>;
  summary: {
    strengths: string[];
    weaknesses: string[];
    improvementAreas: string[];
  };
}

class ScoreService {
  private cache: NodeCache;
  private readonly MAX_RETRIES = 3;
  private readonly DEFAULT_WEIGHT = 1;

  constructor() {
    // 设置缓存，TTL为1小时，每30分钟检查过期
    this.cache = new NodeCache({ 
      stdTTL: 3600,
      checkperiod: 1800,
      useClones: false
    });

    // 设置缓存错误处理
    this.cache.on('error', (err) => {
      logger.error('Cache error:', err);
    });
  }

  /**
   * AI评分主函数
   */
  async evaluateAnswers(data: ScoreData): Promise<ScoreResult> {
    try {
      // 验证输入数据
      this.validateInput(data);

      // 检查缓存
      const cacheKey = this.generateCacheKey(data);
      const cachedResult = this.cache.get<ScoreResult>(cacheKey);
      if (cachedResult) {
        logger.info('Cache hit for score result');
        return cachedResult;
      }

      // 初始化评分结果
      const result: ScoreResult = {
        totalScore: 0,
        details: [],
        summary: {
          strengths: [],
          weaknesses: [],
          improvementAreas: []
        }
      };

      // 计算总权重
      const totalWeight = data.answers.reduce((sum, answer) => 
        sum + (answer.weight || this.DEFAULT_WEIGHT), 0);

      // 对每个答案进行评分
      let retries = 0;
      for (const answer of data.answers) {
        try {
          const scoreDetail = await this.evaluateSingleAnswer(answer);
          result.details.push(scoreDetail);
          // 计算加权分数
          result.totalScore += (scoreDetail.score * (answer.weight || this.DEFAULT_WEIGHT) / totalWeight);
        } catch (error) {
          if (retries < this.MAX_RETRIES) {
            retries++;
            logger.warn(`Retrying evaluation for answer ${answer.questionId}, attempt ${retries}`);
            // 重试当前答案
            answer.questionId === answer.questionId;
          } else {
            throw new ApiError(500, 'EVALUATION_ERROR', '评分失败超过最大重试次数');
          }
        }
      }

      // 生成总结报告
      await this.generateSummary(result);

      // 规范化总分
      result.totalScore = Math.round(result.totalScore * 100) / 100;

      // 缓存结果
      this.cache.set(cacheKey, result);
      logger.info('Score result cached');

      return result;
    } catch (error) {
      logger.error('Score evaluation error:', error);
      throw error instanceof ApiError ? error : new ApiError(500, 'EVALUATION_ERROR', '评分过程发生错误');
    }
  }

  /**
   * 验证输入数据
   */
  private validateInput(data: ScoreData): void {
    if (!data.answers.length) {
      throw new ApiError(400, 'INVALID_INPUT', '答案列表不能为空');
    }

    for (const answer of data.answers) {
      if (!answer.questionId || !answer.answer.trim()) {
        throw new ApiError(400, 'INVALID_INPUT', '答案格式不正确');
      }
      if (answer.weight && (answer.weight <= 0 || answer.weight > 100)) {
        throw new ApiError(400, 'INVALID_INPUT', '题目权重必须在1-100之间');
      }
    }
  }

  /**
   * 评估单个答案
   */
  private async evaluateSingleAnswer(answer: ScoreData['answers'][0]) {
    try {
      // TODO: 接入具体的AI模型
      // 这里模拟AI评分过程
      const score = this.simulateAIScoring(answer.answer);
      const weakPoints = this.identifyWeakPoints(answer.answer);
      
      return {
        questionId: answer.questionId,
        score,
        feedback: this.generateFeedback(score, weakPoints),
        weakPoints,
        suggestions: this.generateSuggestions(score, weakPoints)
      };
    } catch (error) {
      logger.error('Single answer evaluation error:', error);
      throw new ApiError(500, 'EVALUATION_ERROR', '单题评分失败');
    }
  }

  /**
   * 生成评分总结
   */
  private async generateSummary(result: ScoreResult) {
    const details = result.details;
    const summary = result.summary;

    // 分析优势
    summary.strengths = this.analyzeStrengths(details);
    // 分析弱点
    summary.weaknesses = this.analyzeWeaknesses(details);
    // 生成改进建议
    summary.improvementAreas = this.generateImprovementAreas(details);

    // 确保每个数组都有内容
    if (!summary.strengths.length) {
      summary.strengths = ['有待发现优势'];
    }
    if (!summary.weaknesses.length) {
      summary.weaknesses = ['暂无明显问题'];
    }
    if (!summary.improvementAreas.length) {
      summary.improvementAreas = ['继续保持'];
    }
  }

  /**
   * 生成缓存键
   */
  private generateCacheKey(data: ScoreData): string {
    const content = `${data.userId}_${data.subjectId}_${JSON.stringify(data.answers)}`;
    return `score_${crypto.createHash('md5').update(content).digest('hex')}`;
  }

  // 以下是模拟AI评分的辅助方法
  private simulateAIScoring(answer: string): number {
    const baseScore = Math.floor(Math.random() * 40) + 60;
    const length = answer.length;
    
    // 根据答案长度调整分数
    let adjustment = 0;
    if (length < 50) {
      adjustment = -5;
    } else if (length > 500) {
      adjustment = 5;
    }

    return Math.min(100, Math.max(0, baseScore + adjustment));
  }

  private generateFeedback(score: number, weakPoints: string[]): string {
    const baseFeeback = score >= 90 ? '答案非常完整，论述充分，结构清晰' :
                       score >= 80 ? '答案基本完整，有一定的分析深度' :
                       score >= 70 ? '答案有待完善，部分论述不够充分' :
                                   '答案需要大幅改进，建议加强相关知识点的学习';

    return weakPoints.length ? 
      `${baseFeeback}。主要问题：${weakPoints.join('、')}` :
      baseFeeback;
  }

  private identifyWeakPoints(answer: string): string[] {
    const weakPoints = [];
    
    if (answer.length < 50) {
      weakPoints.push('答案过于简短');
    }
    if (answer.split('。').length < 3) {
      weakPoints.push('论述结构不完整');
    }
    if (!answer.includes('例如') && !answer.includes('比如')) {
      weakPoints.push('缺乏具体例证');
    }
    
    return weakPoints;
  }

  private generateSuggestions(score: number, weakPoints: string[]): string[] {
    const suggestions = new Set<string>();

    // 基于分数的建议
    if (score >= 90) {
      suggestions.add('可以尝试拓展更多相关知识');
      suggestions.add('建议学习更深入的专业内容');
    } else if (score >= 80) {
      suggestions.add('加强实例分析');
      suggestions.add('完善论述逻辑');
    } else if (score >= 70) {
      suggestions.add('需要补充基础知识');
      suggestions.add('加强概念理解');
      suggestions.add('增加练习量');
    } else {
      suggestions.add('建议系统复习相关章节');
      suggestions.add('多做基础练习');
      suggestions.add('及时总结错误原因');
    }

    // 基于具体问题的建议
    weakPoints.forEach(point => {
      if (point.includes('简短')) {
        suggestions.add('扩展答案内容，增加论述深度');
      }
      if (point.includes('结构')) {
        suggestions.add('注意答案的逻辑组织和结构完整性');
      }
      if (point.includes('例证')) {
        suggestions.add('增加具体案例和实际应用举例');
      }
    });

    return Array.from(suggestions);
  }

  private analyzeStrengths(details: ScoreResult['details']): string[] {
    const strengths = new Set<string>();
    
    // 分析高分题目的特点
    details.filter(detail => detail.score >= 85).forEach(() => {
      strengths.add('逻辑思维清晰');
      strengths.add('基础知识掌握牢固');
      strengths.add('表达能力较强');
    });

    // 分析答案特点
    if (details.every(detail => detail.score >= 70)) {
      strengths.add('学习态度认真');
      strengths.add('知识掌握均衡');
    }

    return Array.from(strengths);
  }

  private analyzeWeaknesses(details: ScoreResult['details']): string[] {
    // 收集所有低分题目的弱点
    return Array.from(new Set(
      details
        .filter(detail => detail.score < 80)
        .map(detail => detail.weakPoints)
        .flat()
    ));
  }

  private generateImprovementAreas(details: ScoreResult['details']): string[] {
    // 合并所有需要改进的建议
    return Array.from(new Set(
      details
        .filter(detail => detail.score < 85)
        .map(detail => detail.suggestions)
        .flat()
        .sort((a, b) => 
          details.filter(d => d.suggestions.includes(b)).length -
          details.filter(d => d.suggestions.includes(a)).length
        )
        .slice(0, 5) // 只返回最重要的5个建议
    ));
  }

  /**
   * 清理缓存
   * 用于手动清理所有缓存数据
   */
  public clearCache(): void {
    const stats = this.cache.getStats();
    this.cache.flushAll();
    logger.info(`Cache cleared: ${stats.keys} keys removed`);
  }
}

export const scoreService = new ScoreService();
